/*
 *    Copyright 2022 The DSMS Authors.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.dsms.dfsbroker.storagepool.model;

import com.dsms.dfsbroker.storagepool.model.remote.DfResponse;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@Accessors(chain = true)
@NoArgsConstructor
@ApiModel(value = "存储池对象", description = "存储池信息表")
public class StoragePool implements Serializable {

    @ApiModelProperty("存储池id")
    private int poolId;

    @ApiModelProperty("存储池名称")
    private String poolName;

    @ApiModelProperty("存储池类型")
    private int type;

    @ApiModelProperty("存储池pg数")
    private int pgNum;

    @ApiModelProperty("存储池pgp数")
    private int pgpNum;

    @ApiModelProperty("冗余模式(副本池为副本数，纠删码池为k+m)")
    private String redundantMode;

    @ApiModelProperty("存储池包含的rbd列表")
    private String[] rbdList;

    @ApiModelProperty("存储池剩余可分配rbd容量")
    private Long rbdAvailableCapacity;

    @ApiModelProperty("存储池占用的文件系统")
    private String fileSystem;

    @ApiModelProperty("存储池已使用量")
    private Long usedSize;

    @ApiModelProperty("存储池总容量")
    private Long totalSize;

    @ApiModelProperty("存储池是否可用")
    private Boolean isAvailable;

    public StoragePool(int poolId, String poolName, int typeCode, int pgNum, int pgpNum, String redundantMode) {
        this.poolId = poolId;
        this.poolName = poolName;
        this.pgNum = pgNum;
        this.pgpNum = pgpNum;
        this.type = typeCode;
        this.redundantMode = redundantMode;
    }

    public void setCapacity(DfResponse.PoolsDTO dfPool) {
        /*
         * The capacity calculation of the storage pool has two types: "actual capacity" and "ceph capacity":
         * "actual capacity" is the actual use and free space of the disk, and "ceph capacity" is the use and free space after using the ceph storage pool for redundancy
         * From the user perspective, we need to show the "ceph capacity"
         *
         * However,dsms-storage only provides the following three indicators of capacity:
         * maxAvail:the maximum available capacity of the storage pool, which is calculated by ceph through the crush algorithm
         * rawAvail:the real available capacity of the storage pool, which is obtained by directly calculating the free capacity of osd by ceph
         * stored:the used capacity of the storage pool, which is meaning the bytes stored in the pool not including copies
         * storedRaw:the used capacity of the storage pool, which is meaning the bytes used in pool including copies made
         *
         * Therefore,we need to use the following formula to calculate "ceph capacity" and display it to user:
         * totalSize = maxAvail/(rawAvail/(rawAvail+storedRaw))
         * usedSize = stored
         * */
        this.setTotalSize((long) (dfPool.getStats().getMaxAvail() / ((double) dfPool.getStats().getAvailRaw() / (dfPool.getStats().getAvailRaw() + dfPool.getStats().getStoredRaw()))));
        this.setUsedSize((dfPool.getStats().getStored()));
    }
}
